Skip to content

Implement to_d in Numeric and with the same number of arguments everywhere#423

Closed
fsateler wants to merge 1 commit intoruby:masterfrom
fsateler:feature/numeric-to-d
Closed

Implement to_d in Numeric and with the same number of arguments everywhere#423
fsateler wants to merge 1 commit intoruby:masterfrom
fsateler:feature/numeric-to-d

Conversation

@fsateler
Copy link
Copy Markdown
Contributor

@fsateler fsateler commented Sep 8, 2025

This allows user code to be more generic, not having to care
about the specific class.

Preserve the BigDecimal override to allow returning the same object.

--

This is a PoC PR. I don't know if this is desired. But my intuition would be that all Numeric types should be convertible to BigDecimal, with the same interface. What do you think?

Builds on top of #421 to avoid conflicts

@fsateler fsateler changed the title feature/numeric to d Implement to_d in Numeric and with the same number of arguments everywhere Sep 8, 2025
…where

This allows user code to be more generic, not having to care
about the specific class.

Preserve the BigDecimal override to allow returning the same object.
@fsateler fsateler force-pushed the feature/numeric-to-d branch from f66b7dc to 7dbbe1d Compare September 9, 2025 12:10
@tompng
Copy link
Copy Markdown
Member

tompng commented Apr 4, 2026

Thank you for the pull request. However, I think we don't need to make to_d(arg) a common interface for all classes that implements to_d.
obj.to_d is safe but obj.to_d(prec) is not safe even if all to_d methods allows argument.

Reason 1

Ruby's core to_x methods doesn't always implement single-argument version as a common interface. #276 (comment)

string.to_i(2) # OK
nil.to_i(2) # ArgumentError
float.to_i(2) # ArgumentError

Reason 2

Even if NilClass#to_d and String#to_d accepts single argument, to_d(zero_or_positive_integer_prec) it won't be a common interface.

rational.to_d(17) # OK
float.to_d(16) # OK
float.to_d(17) # ArgumentError(precision too large)
complex_with_float_real_part.to_d(20) # ArgumentError

So we still need to consider what is the receiver of to_d to call with argument.
I'm not sure if accepting float.to_d(17) is a good idea. Raising error is beneficial that programmers can know that the code might be doing something wrong.

to_d(17) is not a common interface, programmer need to keep in mind what the receiver type is.

Reason3

Integer#to_d(prec) and String#to_d(prec) might be a misleading spec to add.

# This is misleading, but can't change for backward compatibility
# Maybe we can add a deprecation warning someday, or fix to return 0.123e5
BigDecimal('12345', 3) #=> 0.12345e5
BigDecimal(12345, 3) #=> 0.12345e5

# Allowing this will add another misleading spec
'12345'.to_d(3) #=> 0.12345e5
12345.to_d(3) #=> 0.12345e5

@tompng tompng closed this Apr 4, 2026
@fsateler fsateler deleted the feature/numeric-to-d branch April 6, 2026 20:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants